package order

import (
	"web/global"
	"web/models"
	"web/pkg/util"
)

// 全局变量，用于存储订单项目和评价数据
var (
	orderProjectsMap  map[uint][]*models.LaOrderProject
	orderEvaluatesMap map[uint64][]*models.LaOrderEvaluate
)

type FillOrderService struct {
}

// 创建填充服务实例
func NewFillOrderService() *FillOrderService {
	return &FillOrderService{}
}

// FillOne 填充单个订单信息
func (s *FillOrderService) FillOne(order *models.LaOrder, options util.FillOption) {
	s.Fill([]*models.LaOrder{order}, options)
}

// Fill 填充多个订单信息
func (s *FillOrderService) Fill(orders []*models.LaOrder, options util.FillOption) {
	if len(orders) == 0 {
		return
	}

	// 支持 order_items 和 with_order_projects 两种选项名称
	if v, ok := options["order_items"]; ok && v {
		s.fillOrderProjects(orders)
	} else if v, ok := options["with_order_projects"]; ok && v {
		s.fillOrderProjects(orders)
	}

	// 支持 order_evaluate 和 with_order_evaluates 两种选项名称
	if v, ok := options["order_evaluate"]; ok && v {
		s.fillOrderEvaluates(orders)
	} else if v, ok := options["with_order_evaluates"]; ok && v {
		s.fillOrderEvaluates(orders)
	}
}

// fillOrderProjects 查询订单项目信息
func (s *FillOrderService) fillOrderProjects(orders []*models.LaOrder) {
	if len(orders) == 0 {
		return
	}

	orderIds := make([]uint, 0, len(orders))
	for _, order := range orders {
		orderIds = append(orderIds, uint(order.ID))
	}

	// 查询订单项目
	var orderProjects []*models.LaOrderProject
	if err := global.DB.Where("order_id IN ?", orderIds).Find(&orderProjects).Error; err != nil {
		return
	}

	// 将订单项目存储到上下文中，供响应编码使用
	orderIdToProjects := make(map[uint][]*models.LaOrderProject)
	for _, project := range orderProjects {
		if _, ok := orderIdToProjects[project.OrderID]; !ok {
			orderIdToProjects[project.OrderID] = make([]*models.LaOrderProject, 0)
		}
		orderIdToProjects[project.OrderID] = append(orderIdToProjects[project.OrderID], project)
	}

	// 将订单项目映射存储到上下文中
	// 注意：context是不可变的，所以我们需要创建一个新的context并替换
	// 但由于我们无法修改传入的context，我们将使用一个全局变量来存储这些数据
	// 在实际应用中，可以考虑使用其他方式，如依赖注入或单例模式
	if orderProjectsMap == nil {
		orderProjectsMap = make(map[uint][]*models.LaOrderProject)
	}
	for k, v := range orderIdToProjects {
		orderProjectsMap[k] = v
	}
}

// fillOrderEvaluates 查询订单评价信息
func (s *FillOrderService) fillOrderEvaluates(orders []*models.LaOrder) {
	if len(orders) == 0 {
		return
	}

	orderIds := make([]uint64, 0, len(orders))
	for _, order := range orders {
		orderIds = append(orderIds, uint64(order.ID))
	}

	// 查询订单评价
	var orderEvaluates []*models.LaOrderEvaluate
	if err := global.DB.Where("order_id IN ?", orderIds).Find(&orderEvaluates).Error; err != nil {
		return
	}

	// 将订单评价存储到上下文中，供响应编码使用
	orderIdToEvaluates := make(map[uint64][]*models.LaOrderEvaluate)
	for _, evaluate := range orderEvaluates {
		if _, ok := orderIdToEvaluates[evaluate.OrderID]; !ok {
			orderIdToEvaluates[evaluate.OrderID] = make([]*models.LaOrderEvaluate, 0)
		}
		orderIdToEvaluates[evaluate.OrderID] = append(orderIdToEvaluates[evaluate.OrderID], evaluate)
	}

	// 将订单评价映射存储到上下文中
	// 注意：context是不可变的，所以我们需要创建一个新的context并替换
	// 但由于我们无法修改传入的context，我们将使用一个全局变量来存储这些数据
	// 在实际应用中，可以考虑使用其他方式，如依赖注入或单例模式
	if orderEvaluatesMap == nil {
		orderEvaluatesMap = make(map[uint64][]*models.LaOrderEvaluate)
	}
	for k, v := range orderIdToEvaluates {
		orderEvaluatesMap[k] = v
	}
}

// GetOrderProjects 获取订单项目信息
func (s *FillOrderService) GetOrderProjects(orderID uint) []*models.LaOrderProject {
	if orderProjectsMap == nil {
		return nil
	}
	if projects, ok := orderProjectsMap[orderID]; ok {
		return projects
	}
	return nil
}

// GetOrderEvaluates 获取订单评价信息
func (s *FillOrderService) GetOrderEvaluates(orderID uint64) []*models.LaOrderEvaluate {
	if orderEvaluatesMap == nil {
		return nil
	}
	if evaluates, ok := orderEvaluatesMap[orderID]; ok {
		return evaluates
	}
	return nil
}
